package abacab.remote.oio;

import java.io.IOException;
import java.net.InetSocketAddress;
import java.net.ServerSocket;
import java.net.Socket;

import abacab.remote.ConnectionRegistry;
import abacab.remote.protocol.Acceptor;

/**
 * An acceptor for socket connections
 */
@SuppressWarnings("synthetic-access")
public class SocketAcceptor implements Acceptor {
	/** The registry */
	private final ConnectionRegistry	registry;

	/** The server socket */
	private final ServerSocket				socket;

	/** Indicates if the acceptor should be stopped */
	private volatile boolean					stopped;

	/**
	 * Create the acceptor
	 * 
	 * @param registry
	 *          the registry
	 * @throws IOException
	 *           if an error occurred
	 */
	public SocketAcceptor(ConnectionRegistry registry) throws IOException {
		this.registry = registry;
		this.socket = new ServerSocket();
		this.socket.bind(new InetSocketAddress(registry.getNetworkInterface(), registry.getListeningPort()));
		new Thread(new Acceptor(), "socket acceptor: " + this.socket.getLocalSocketAddress()).start();
	}

	@Override
	public void stop() {
		this.stopped = true;
	}

	/**
	 * The acceptor
	 */
	private final class Acceptor implements Runnable {
		@Override
		@SuppressWarnings("unused")
		public void run() {
			try {
				while (!SocketAcceptor.this.stopped) {
					Socket connection = SocketAcceptor.this.socket.accept();
					// Create the connection
					new SocketClient(SocketAcceptor.this.registry, connection);
				}
			}
			catch (IOException e) {
				if (!SocketAcceptor.this.stopped) {
					// TODO: fatal !!!
				}
			}
		}
	}
}